package people;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import utilities.Security;

/**
 * The System Admin class; the person who has the priorities to do 
 * stuff within the system
 * @author Peter
 *
 * @version $Revision: 1.0 $
 */
public class SystemAdmin extends Person{
	
	/**
	 * Field current
	 */
	private Person current;

	/**
	 * Field patientDB - get from database
	 */
	private Map<String, Patient> patientDB;
	
	/**
	 * Field nurseDB - get from database
	 */
	private Map<String, Nurse> nurseDB;
	
	/**
	 * Field doctorDB - get from database
	 */
	private Map<String, Doctor> doctorDB;
	
	/**
	 * Field sysAdminDB - get from database
	 */
	private Map<String, SystemAdmin> adminDB;
	
	/**
	 * Field patientNameDB - get from database
	 */
	private Map<String, List<String>> patientNameDB;
	
	/**
	 * Field employeeNameDB - get from database
	 */
	private Map<String, List<String>> employeeNameDB;
	
	/**
	 * Field employeeNameDB - get from database
	 */
	private Security securityInt;
	
	/**
	 * Constructor that creates a system admin <!-- // $codepro.audit.disable spellCheckComments -->
	 * @param fName - system admin's first name
	 * @param lName - system admin's last name
	 */
	public SystemAdmin(String fName, String lName) {
		super(fName, lName);
		securityInt = new Security();
		setPersonType(UserType.ADMIN);
		//auto-gen username by default
		//get the lists from database
			//right now, just initialize the lists
		patientDB = new HashMap<String, Patient>();
		nurseDB = new HashMap<String, Nurse>();
		doctorDB = new HashMap<String, Doctor>();
		adminDB = new HashMap<String, SystemAdmin>();
		patientNameDB = new HashMap<String, List<String>>();
		employeeNameDB = new HashMap<String, List<String>>();
		MYLOGGER.info("In SystemAdmin constructor");
	}
	
	/**
	 * Searches for a person in the system
	 * @param uName - person's username or real name
	 * @param isUserName - determines whether to search by username or real name
	 * @param type - if the person is a patient, nurse, doctor, or a system admin 
	 * @return a list of username(s) that the input uName maps to
	 */
	public List<String> searchUser(String uName, UserType type, boolean isUserName){
		if(type == null){
			return new LinkedList<String>();
		}
		List<String> userList = new LinkedList<String>();
		MYLOGGER.info("System Admin is trying to search for user");
		
		switch(type) {
		case PATIENT:
			if(!isUserName){
				if(patientNameDB.get(uName) == null){
					return new LinkedList<String>();
				}
				else{
					return patientNameDB.get(uName); 
				}
			}
			current = patientDB.get(uName);
			break;
		case NURSE:
		case DOCTOR:
		case ADMIN:
			if(!isUserName){
				if(employeeNameDB.get(uName) == null){
					return new LinkedList<String>();
				}
				else{
					List<String> aList = employeeNameDB.get(uName);
					for(int i = 0; i < aList.size(); i++){
						
						switch(type){
						case NURSE:
							current = nurseDB.get(aList.get(i));
							break;
						case DOCTOR:
							current = doctorDB.get(aList.get(i));
							break;
						case ADMIN:
							current = adminDB.get(aList.get(i));
						}
						
						if(current != null){
							userList.add(current.getUserID());
						}
					}
					return userList; 
				}
			}
			switch(type){
			case NURSE:
				current = nurseDB.get(uName);
				break;
			case DOCTOR:
				current = doctorDB.get(uName);
				break;
			case ADMIN:
				current = adminDB.get(uName);
			}
		}
		if(current != null){
		userList.add(uName);
		}
		return userList;
	}
	
	/**
	 * Create a user with an assigned type
	 * @param fName
	 * @param lName
	 * @param type
	 * @return true if user was created, false otherwise
	 */
	public boolean createUser(String fName, String lName, UserType type){
		String temp = lName + " " + fName;
		List<String> placeHolder;
		MYLOGGER.info("System Admin is trying to create an account for user");
		
		switch(type) {
		case PATIENT:
			final Patient aPatient = new Patient(fName, lName);
			patientDB.put(aPatient.getUserID(), aPatient);
			placeHolder = patientNameDB.get(temp); 
			if(placeHolder == null){
				List<String> nameList = new LinkedList<String>();
				nameList.add(aPatient.getUserID());
				patientNameDB.put(temp, nameList);
			}
			else{
			placeHolder.add(aPatient.getUserID());
			patientNameDB.put(temp, placeHolder);
			current = aPatient;
			}
			return true;
		case NURSE:
			final Nurse aNurse = new Nurse(fName, lName);
			nurseDB.put(aNurse.getUserID(), aNurse);
			placeHolder = employeeNameDB.get(temp); 
			if(placeHolder == null){
				List<String> nameList = new LinkedList<String>();
				nameList.add(aNurse.getUserID());
				employeeNameDB.put(temp, nameList);
			}
			else{
			placeHolder.add(aNurse.getUserID());
			employeeNameDB.put(temp, placeHolder);
			current = aNurse;
			}
			return true;
		case DOCTOR:
			final Doctor aDoctor = new Doctor(fName, lName);
			doctorDB.put(aDoctor.getUserID(), aDoctor);
			placeHolder = employeeNameDB.get(temp); 
			if(placeHolder == null){
				List<String> nameList = new LinkedList<String>();
				nameList.add(aDoctor.getUserID());
				employeeNameDB.put(temp, nameList);
			}
			else{
			placeHolder.add(aDoctor.getUserID());
			employeeNameDB.put(temp, placeHolder);
			current = aDoctor;
			}
			return true;
		case ADMIN:
			final SystemAdmin anAdmin = new SystemAdmin(fName, lName);
			adminDB.put(anAdmin.getUserID(), anAdmin);
			placeHolder = employeeNameDB.get(temp); 
			if(placeHolder == null){
				List<String> nameList = new LinkedList<String>();
				nameList.add(anAdmin.getUserID());
				employeeNameDB.put(temp, nameList);
			}
			else{
			placeHolder.add(anAdmin.getUserID());
			employeeNameDB.put(temp, placeHolder);
			current = anAdmin;
			}
			return true;
		}
		return false;
	}

	/**
	 * Delete a user from system
	 * @param uName
	 * @param type
	 * @return true if user is deleted, false otherwise
	 */
	public boolean deleteUser(String uName, UserType type){
		MYLOGGER.info("System Admin is trying to delete an account for user");
		switch(type){
		case PATIENT:
			final Patient removed = patientDB.remove(uName);
			if (removed != null) {
				String temp = removed.getLastName() + " " + removed.getFirstName();
				List<String> tempholder = patientNameDB.get(temp);
				tempholder.remove(uName);
				MYLOGGER.info("Patient deleted from system");
				return true;
			}
			MYLOGGER.warning("Patient not found in system, abort deletion");
			return false;
		case NURSE:
			//do later
		case DOCTOR:
			//do later
		case ADMIN:
			//do later
		}
		MYLOGGER.warning("No type entered, abort deletion");
		return false;
	}
	
	/**
	 * Resets the user's password
	 */
	public String resetPassword(){
		MYLOGGER.info("System Admin resetting user's password");
		return securityInt.resetPassword(current);
	}
	
	/**
	 * Modify user details
	 */
	public void modifyUser(){
		MYLOGGER.info("System Admin is trying to modify user details");
		//pulls up on UI choices to make changes to
	}

	/**
	 * Overrides the default toString method
	 * @return System Admin's name
	 */
	public String toString(){
		return "System Admin: " + this.getFirstName() + " " + this.getLastName();
	}
}
